package com.shuyu.task;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.shuyu.common.constant.Constants;
import com.shuyu.common.utils.StringUtils;
import com.shuyu.common.utils.nft.NFTUtils;
import com.shuyu.common.utils.nft.domain.MetadataVo;
import com.shuyu.common.utils.nft.domain.NFTVo;
import com.shuyu.common.utils.sign.Md5Utils;
import com.shuyu.domain.NFT;
import com.shuyu.domain.NftTransfer;
import com.shuyu.domain.Product;
import com.shuyu.service.NFTService;
import com.shuyu.service.NftTransferService;
import com.shuyu.service.ProductService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * 定时任务调度测试
 * 
 * @author ruoyi
 */
@Component("nftTask")
public class NFTTask
{
    public static final Logger log = LoggerFactory.getLogger(NFTTask.class);
    @Resource
    private ProductService productService;
    @Resource
    private NftTransferService nftTransferService;
    @Resource
    private NFTService nftService;

    public void createNft()
    {
        log.info("执行铸造NFT方法开始");
        //铸造NFT
        try {
            List<Product> productList = productService.list(new LambdaQueryWrapper<Product>().eq(Product::getType, 1)
                    .eq(Product::getNftCreateStatus, 0).eq(Product::getNftCreateTaskStatus,1));
            for (Product product : productList) {
                int quantity = product.getQuantity();
                int productId = product.getId();
                int count = nftService.count(new LambdaQueryWrapper<NFT>().eq(NFT::getProductId, productId));
                if(count == quantity){
                    log.info("执行铸造NFT方法【"+productId+"】【"+product.getName()+"】【已经生成对应nft数量"+count+"】");
                    productService.update(new LambdaUpdateWrapper<Product>().set(Product::getNftCreateStatus,1).eq(Product::getId, productId));
                    continue;
                }
                int mintingCount = quantity - count;
                log.info("执行铸造NFT方法【"+productId+"】【"+product.getName()+"】【铸造nft数量"+mintingCount+"】开始");
                for (int i = 1; i <= mintingCount; i++) {
                    MetadataVo metadata = new MetadataVo(i+"",product.getName()+"#"+i,product.getImg(),product.getIntroduction(), product.getIssuingCompany(),
                            product.getProductionCompany());
                    String metadataString = JSONObject.from(metadata).toString();
                    String contractAddress = product.getContractAddress();
                    if(StringUtils.isEmpty(contractAddress)){
                        contractAddress = Constants.CONTRACT_ADDRESS;
                    }
                    NFTVo nftVo = NFTUtils.createNFT(metadataString,contractAddress);
                    String collectionCode = Md5Utils.hash(nftVo.getTokenId().toString()+"didol"+productId);
                    NFT nft = new NFT(productId, nftVo.getTransactionHash(), nftVo.getTokenId(), collectionCode, Constants.WALLET_ADDRESS, new Date());
                    nftService.save(nft);
                    NftTransfer nftTransfer = new NftTransfer(nft.getId(), nftVo.getTransactionHash(), nft.getTokenId(), Constants.INIT_WALLET_ADDRESS, Constants.WALLET_ADDRESS, "minting", new Date(),"数与（杭州）文化科技有限公司");
                    nftTransferService.save(nftTransfer);
                }
                productService.update(new LambdaUpdateWrapper<Product>().set(Product::getNftCreateStatus,1).eq(Product::getId, productId));
                log.info("执行铸造NFT方法【"+productId+"】【"+product.getName()+"】【铸造nft数量"+mintingCount+"】完成");
            }

        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        log.info("执行铸造NFT方法结束");

    }
}
